import React, { Component, RefObject } from "react";
import Flipper from "../Flipper";
import "./index.css";

interface FlipClockState {
    hou: string;
    second: string;
    minutes: string;
    strikes: number;
    oneHour: boolean;
    halfHour: boolean;
}

class FlipClock extends Component<{}, FlipClockState> {
    private timer: NodeJS.Timeout | null = null;
    private flipObjs: Flipper[] = [];
    private flipperHour1: RefObject<Flipper>;
    private flipperHour2: RefObject<Flipper>;
    private flipperMinute1: RefObject<Flipper>;
    private flipperMinute2: RefObject<Flipper>;
    private flipperSecond1: RefObject<Flipper>;
    private flipperSecond2: RefObject<Flipper>;

    constructor(props: {}) {
        super(props);
        this.state = {
            hou: "00",
            second: "00",
            minutes: "00",
            strikes: 0,
            oneHour: false,
            halfHour: false,
        };

        this.flipperHour1 = React.createRef();
        this.flipperHour2 = React.createRef();
        this.flipperMinute1 = React.createRef();
        this.flipperMinute2 = React.createRef();
        this.flipperSecond1 = React.createRef();
        this.flipperSecond2 = React.createRef();
    }

    componentDidMount() {
        this.flipObjs = [
            this.flipperHour1.current!,
            this.flipperHour2.current!,
            this.flipperMinute1.current!,
            this.flipperMinute2.current!,
            this.flipperSecond1.current!,
            this.flipperSecond2.current!,
        ];
        this.init();
    }

    private init(): void {
        for (let i = 0; i < this.flipObjs.length; i++) {
            this.flipObjs[i].setFront(0);
        }
    }

    public run = (): void => {
        this.timer = setInterval(() => {
            const nextstrikes = this.state.strikes + 1000;
            const o_nextstrikes = nextstrikes + 1000;

            const hou = parseInt(String(nextstrikes / 3600000)) % 24;
            const minutes = parseInt(String(nextstrikes / 60000)) % 60;
            const second = parseInt(String(nextstrikes / 1000)) % 60;

            const o_hou = parseInt(String(o_nextstrikes / 3600000)) % 24;
            const o_minutes = parseInt(String(o_nextstrikes / 60000)) % 60;
            const o_second = parseInt(String(o_nextstrikes / 1000)) % 60;

            const n_hou = o_hou <= 9 ? "0" + o_hou : String(o_hou);
            const n_minutes =
                o_minutes <= 9 ? "0" + o_minutes : String(o_minutes);
            const n_second = o_second <= 9 ? "0" + o_second : String(o_second);

            const nextTimeStr = n_hou + n_minutes + n_second;

            this.setState(
                {
                    hou: hou <= 9 ? "0" + hou : String(hou),
                    minutes: minutes <= 9 ? "0" + minutes : String(minutes),
                    second: second <= 9 ? "0" + second : String(second),
                    strikes: nextstrikes,
                    oneHour: 10000 <= parseInt(nextTimeStr),
                    halfHour: 3000 <= parseInt(nextTimeStr),
                },
                () => {
                    const { hou, minutes, second } = this.state;
                    const nowTimeStr = hou + minutes + second;

                    for (let i = 0; i < this.flipObjs.length; i++) {
                        if (nowTimeStr[i] === nextTimeStr[i]) {
                            continue;
                        }
                        this.flipObjs[i].flipDown(
                            parseInt(nowTimeStr[i]),
                            parseInt(nextTimeStr[i])
                        );
                    }
                }
            );
        }, 1000);
    };

    public end = (): void => {
        if (this.timer) {
            clearInterval(this.timer);
        }
    };

    public stop = (): void => {
        if (this.timer) {
            clearInterval(this.timer);
        }
    };

    public getUseTime = (): string => {
        const { hou, minutes, second } = this.state;
        return hou + minutes + second;
    };

    componentWillUnmount() {
        if (this.timer) {
            clearInterval(this.timer);
        }
    }

    render() {
        const { oneHour, halfHour } = this.state;
        return (
            <div className="FlipClock">
                <Flipper
                    ref={this.flipperHour1}
                    oneHour={oneHour}
                    halfHour={halfHour}
                />
                <Flipper
                    ref={this.flipperHour2}
                    oneHour={oneHour}
                    halfHour={halfHour}
                />
                <em>:</em>
                <Flipper
                    ref={this.flipperMinute1}
                    oneHour={oneHour}
                    halfHour={halfHour}
                />
                <Flipper
                    ref={this.flipperMinute2}
                    oneHour={oneHour}
                    halfHour={halfHour}
                />
                <em>:</em>
                <Flipper
                    ref={this.flipperSecond1}
                    oneHour={oneHour}
                    halfHour={halfHour}
                />
                <Flipper
                    ref={this.flipperSecond2}
                    oneHour={oneHour}
                    halfHour={halfHour}
                />
            </div>
        );
    }
}

export default FlipClock;
